﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using DHJ.Cost.Analysis.Dto;
using DHJ.Cost.RealTimeCost.Dto;
using DHJ.Cost.Timing;
using DHJ.Cost.Workshops;
using Microsoft.EntityFrameworkCore;

namespace DHJ.Cost.RealTimeCost
{
    public class EstimatedCostAppService : CostAppServiceBase, IEstimatedCostAppService
    {
        private readonly IRepository<EstimatedCost, Guid> _estimatedCostRepository;

        public EstimatedCostAppService(
            IRepository<EstimatedCost, Guid> estimatedCostRepository
        )
        {
            _estimatedCostRepository = estimatedCostRepository;
        }

        public async Task<EstimatedBatchCostDto> GetEstimatedCostByBatchId(string batchId)
        {
            var cost = await _estimatedCostRepository.GetAll().Where(e => e.BatchId == batchId).GroupBy(e => e.BatchId)
                .Select(g => new EstimatedBatchCostDto()
                {
                    BatchId = g.Key,
                    Quantity = g.First().Quantity,
                    Amount = g.Sum(e => e.Amount),
                    Costs = new List<EstimatedCostDto>(),
                    TypeCosts = g.GroupBy(e => e.Category).Select(g1 => new EstimatedCategoryCostDto()
                    {
                        Amount = g1.Sum(e => e.Amount),
                        Category = g1.Key
                    }).ToList()
                }).FirstOrDefaultAsync();


            return cost;
        }

        public async Task<PagedResultDto<EstimatedCostDto>> GetEstimatedCosts(GetEstimatedCostsInput input)
        {
            var query = _estimatedCostRepository.GetAll()
                .WhereIf(!string.IsNullOrWhiteSpace(input.Workshop), e => e.Workshop == input.Workshop)
                .WhereIf(!string.IsNullOrWhiteSpace(input.BatchId), e => e.BatchId == input.BatchId)
                .WhereIf(input.Year.HasValue && input.Month.HasValue,
                    e => e.Time >= input.GetTime().GetStartDate() && e.Time <= input.GetTime().GetEndDate())
                    .WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => e.BatchId.Contains(input.Filter) || e.Type.Contains(input.Filter) || e.Category.Contains(input.Filter));

            var totalCount = await query.CountAsync();

            var costs = await query.OrderBy("CreationTime desc").PageBy(input).ToListAsync();

            return new PagedResultDto<EstimatedCostDto>(totalCount, ObjectMapper.Map<List<EstimatedCostDto>>(costs));
        }

        /// <summary>
        /// 获得月份的 条码成本信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<EstimatedBatchCostDto>> GetMonthlyBatchIdEstimatedCosts(
            GetEstimatedCostsInput input)
        {
            var query = _estimatedCostRepository.GetAll()
                .WhereIf(!string.IsNullOrWhiteSpace(input.Workshop), e => e.Workshop == input.Workshop)
                .WhereIf(!string.IsNullOrWhiteSpace(input.BatchId), e => e.BatchId == input.BatchId)
                .WhereIf(input.Year.HasValue && input.Month.HasValue,
                    e => e.Time >= input.GetTime().GetStartDate() && e.Time <= input.GetTime().GetEndDate())
                     .WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => e.BatchId.Contains(input.Filter) || e.Type.Contains(input.Filter) || e.Category.Contains(input.Filter));

            var groupQuery = query.GroupBy(e => e.BatchId);

            var totalCount = await groupQuery.CountAsync();

            var costs = await groupQuery.PageBy(input).ToListAsync();

            var dtos = new List<EstimatedBatchCostDto>();

            foreach (var cost in costs)
            {
                var dto = new EstimatedBatchCostDto
                {
                    BatchId = cost.Key,
                    Quantity = cost.First().Quantity,
                    Amount = cost.Sum(e => e.Amount),
                    Costs = new List<EstimatedCostDto>(),
                    TypeCosts = cost.GroupBy(e => e.Category).Select(g => new EstimatedCategoryCostDto()
                    {
                        Amount = g.Sum(e => e.Amount), Category = g.Key
                    }).ToList()
                };


                dtos.Add(dto);
            }

            return new PagedResultDto<EstimatedBatchCostDto>(totalCount, dtos);
        }


        public async Task<ListResultDto<EstimatedWorkshopCostDto>> GetWorkshopEstimatedCosts(int year, int month)
        {
            var time = new Time(year , month);

            var query = _estimatedCostRepository.GetAll().Where(e => e.Time >= time.GetStartDate() && e.Time <= time.GetEndDate())
                .GroupBy(e => new { e.Workshop, e.Category })
                .Select(g => new EstimatedWorkshopCostDto()
                {
                    Workshop = g.Key.Workshop,
                    Category = g.Key.Category,
                    Amount = g.Sum(e => e.Amount)
                });

            return new ListResultDto<EstimatedWorkshopCostDto>(await query.ToListAsync());
        }
    }
}